package j.quartz.ui.sys.conf;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import j.quartz.ui.common.utils.SpringContextUtil;
import j.quartz.ui.sys.cache.SpringCacheManagerWrapper;
import j.quartz.ui.sys.shiro.authc.RetryLimitHashedCredentialsMatcher;
import j.quartz.ui.sys.shiro.realm.SysUserRealm;

/**
 * 配置Shiro相关信息
 * @author Wator
 * 
 * 解释：继承 AppCtxConfig，达到提前注入ApplicationContext的目的
 * 
 */
@Configuration
public class ShiroConfiguration extends AppCtxConfig {
	
	 /**
	  * 权限管理，配置主要是Realm的管理认证
	  */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(
        		sysUserRealm()
        		);
        return securityManager;
    }
    
	/**
	 * 自定义的 Realm
	 */
	@Bean
	public SysUserRealm sysUserRealm() {
		SysUserRealm realm = new SysUserRealm() ;
		realm.setAuthenticationCachingEnabled(false); 
		realm.setAuthorizationCachingEnabled(false);
		
		realm.setCredentialsMatcher(
				credentialsMatcher()
				);
		return realm; 
	}
	

	/**
	 * Filter工厂，设置对应的过滤条件和跳转条件
	 */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        Map<String,String> filterChainDefinitionMap = new HashMap<String, String>();
        
        // 静态资源过滤
        filterChainDefinitionMap.put("/static_jq/**","anon");
        // 验证码过滤
        filterChainDefinitionMap.put("/jcaptcha*","anon");
        // 文件上传过滤
        filterChainDefinitionMap.put("/upload/**","anon");
        
        //首页 【这个配置要往前放】
        shiroFilterFactoryBean.setSuccessUrl("/index");
        
        //登录页面
        filterChainDefinitionMap.put("/user/toLogin","anon");
        shiroFilterFactoryBean.setLoginUrl("/user/toLogin");
        
        // 登录动作不需要权限验证
        filterChainDefinitionMap.put("/user/login","anon");
        
        //登出
        filterChainDefinitionMap.put("/user/logout","anon");
        // 有admin角色
        filterChainDefinitionMap.put("/admin","roles[admin]") ;
        
        //对所有用户认证
//        filterChainDefinitionMap.put("/**","authc");
        
        //错误页面，认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        
        // 架构重写Shiro的Filter和自定义的Filter加入到该Map中
        Map<String, Filter> filters = new HashMap<String, Filter>() ;
//        filters.put("/user/logout", logoutFilter()) ;
        
        
        shiroFilterFactoryBean.setFilters(filters);
        
        return shiroFilterFactoryBean;
    }
    
	@Bean
	public SpringCacheManagerWrapper shiroCacheManager() {
		SpringCacheManagerWrapper shiroCacheManager = new SpringCacheManagerWrapper() ;
		EhCacheCacheManager cacheManager = SpringContextUtil.getBean("springCacheManager") ;
		shiroCacheManager.setCacheManager(cacheManager);
		return shiroCacheManager;
	}
	
	@Bean
	public RetryLimitHashedCredentialsMatcher credentialsMatcher() {
		RetryLimitHashedCredentialsMatcher credentialsMatcher = 
				new RetryLimitHashedCredentialsMatcher(
						shiroCacheManager()
						);
		
		credentialsMatcher.setHashAlgorithmName("md5");
		credentialsMatcher.setHashIterations(2);
		credentialsMatcher.setStoredCredentialsHexEncoded(true);
		
		return credentialsMatcher;
	}
	
	
	 /**
	  * 加入注解的使用，不加入这个注解不生效
	  */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

//    @Bean
    public LogoutFilter logoutFilter() {
    	LogoutFilter logoutFilter = new LogoutFilter() ;
    	logoutFilter.setRedirectUrl("/user/toLogin?logout=1");
    	return logoutFilter;
    }
    
    
    
    
}
